home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part2 / 15186 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  2.9 KB

  1. Path: druid.borland.com!usenet
  2. From: pete@borland.com (Pete Becker)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: A little shift to the left and a little shift to the right.
  5. Date: 17 Apr 1996 18:26:43 GMT
  6. Organization: Borland International
  7. Message-ID: <4l3d53$dom@druid.borland.com>
  8. References: <4knegm$40d@crl.crl.com>
  9. NNTP-Posting-Host: pbecker.borland.com
  10. Mime-Version: 1.0
  11. Content-Type: Text/Plain; charset=ISO-8859-1
  12. X-Newsreader: WinVN 0.99.5
  13.  
  14. In article <4knegm$40d@crl.crl.com>, smuegge@crl.com says...
  15. >
  16. >Our trusty PL/M-to-C translator generated the C operators << and >>
  17. >whenever it encountered the PL/M operators SHL and SHR. 
  18. >
  19. >In one case the original coder had used these bit shifting operators
  20. >to clear out the top nibble of a byte using the following code. 
  21. >(Actually this is the C code the translator generated less the
  22. >proprietary variable names. :))
  23. >
  24. >   x = ( ( y << 4 ) >> 4 );
  25. >
  26. >   (The name of the coder will remain a secret, and yes I know a
  27. >    simple "& 0x0f" would be a more obvious solution. but the same
  28. >    problem is exhibited for any left-shift followed by a right-shift)
  29. >
  30. >Both the variables x and y are bytes ( unsigned chars ). 
  31. >
  32. >The results of this code is the the value of y is assigned to
  33. >x without any modification.  The same results as simple assignment
  34. >(x = y).  It turns out that every C compiler I've tried ( Intel-C,
  35. >Microsoft VC++, and gcc) exhibits this same behaviour. 
  36. >Looking at the assembly code generated by all three compilers the
  37. >reason the shifts have no effect is because they do them with 32 
  38. >bit registers.  So, when the bits are shifted to the left by 4 they
  39. >aren't "lost" as one might expect.  Then the right shift just 
  40. >returns all the bits to original position. 
  41. >
  42. >By using a typecast two of the compilers (Intel-C and gcc) will 
  43. >do what the original coder intended, mask off the the top nibble of
  44. >a byte. Microsoft's compiler just ignored the typecast and 
  45. >generated the same code as it did without the typecast.
  46. >
  47. >  x = ( ( unsigned char ) ( y << 4 ) >> 4 );
  48. >
  49. >Also, seperating the two shifts into two statements all the compilers
  50. >work as originally hoped.
  51. >
  52. >  x = y << 4;
  53. >  x = x >> 4;
  54. >
  55. >Anyway, any experts in C want to tell me whether these compilers
  56. >are just doing these operations correctly or incorrectly?  Also,
  57. >what about the fact that the Microsoft compiler ignores the typecast
  58. >unlike Intel-C and gcc?  Also, if any experts in human behaviour
  59. >want to tell me why I care, I would appreciate that too.
  60.  
  61. Before doing any shift operations the compiler performs the integral 
  62. promotions, so the shift in y<<4 is being done on an integer, not an unsigned 
  63. char. The version with the cast should do what you want, because it tells the 
  64. compiler to ignore any bits out beyond the end of an unsigned char when it does 
  65. the shift right. This means that the high bits should get filled with zeros. Of 
  66. course, the final version works because the value of the left shift is 
  67. explicitly stored as an unsigned char.
  68.     -- Pete
  69.  
  70.